export default class GestureDetector {

    private _onStart: Function = null;

    private _onMove: Function = null;

    private _onEnd: Function = null;

    private lastPos: cc.Vec2 = cc.v2();
    private startPos: cc.Vec2 = cc.v2();
    private isTouching: boolean = false;

    constructor(com: cc.Component | cc.Node) {
        if (!com) {
            return;
        }
        const comp = com instanceof cc.Component ? com.node : com;
        comp.on(cc.Node.EventType.TOUCH_START, this.onTouchStart, this);
        comp.on(cc.Node.EventType.TOUCH_MOVE, this.onTouchMove, this);
        comp.on(cc.Node.EventType.TOUCH_END, this.onTouchEnd, this);
        comp.on(cc.Node.EventType.TOUCH_CANCEL, this.onTouchEnd, this)
    }

    public onBeginTouch(onstart: (p: cc.Vec2) => void) {
        this._onStart = onstart
    }

    public onEndTouch(onEnd: (p: cc.Vec2) => void) {
        this._onEnd = onEnd
    }

    public onDrag(onMove: (p: cc.Vec2, delta: cc.Vec2, dist?: cc.Vec2) => void) {
        this._onMove = onMove
    }

    private onTouchStart(ev: cc.Touch) {
        this.isTouching = true;

        this.lastPos.set(ev.getLocation());
        this.startPos.set(ev.getLocation());
        if (this._onStart) {
            this._onStart(this.lastPos);
        }
    }

    private onTouchMove(ev: cc.Touch) {
        if (!this.isTouching) {
            return
        }
        this.lastPos.set(ev.getLocation());

        if (this._onMove) {
            this._onMove(ev.getLocation(), ev.getDelta(), this.lastPos.sub(this.startPos, cc.v2()));
        }

    }

    private onTouchEnd(ev: cc.Touch) {
        this.isTouching = false;
        this.lastPos.x = 0;
        this.lastPos.y = 0;
        if (this._onEnd) {
            this._onEnd(ev.getLocation())
        }
    }
}